register_portio_handler(v->domain, PIT_BASE, 4, handle_pit_io);
register_portio_handler(v->domain, 0x61, 1, handle_speaker_io);
- ticks_per_sec(v) = cpu_khz * (int64_t)1000;
-
pit_reset(v->domain);
}
cpuid(1, &eax, &ebx, &ecx, &edx);
hdr->cpuid = eax;
- hdr->pad0 = 0;
+ /* Save guest's preferred TSC. */
+ hdr->gtsc_khz = d->arch.hvm_domain.gtsc_khz;
}
int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr)
gdprintk(XENLOG_WARNING, "HVM restore: saved CPUID (%#"PRIx32") "
"does not match host (%#"PRIx32").\n", hdr->cpuid, eax);
+ /* Restore guest's preferred TSC frequency. */
+ d->arch.hvm_domain.gtsc_khz = hdr->gtsc_khz;
+
/* VGA state is not saved/restored, so we nobble the cache. */
d->arch.hvm_domain.stdvga.cache = 0;
spin_lock_init(&pl->pl_time_lock);
pl->stime_offset = -(u64)get_s_time();
pl->last_guest_time = 0;
+
+ d->arch.hvm_domain.gtsc_khz = cpu_khz;
}
u64 hvm_get_guest_time(struct vcpu *v)
struct hvm_ioreq_page ioreq;
struct hvm_ioreq_page buf_ioreq;
- s64 tsc_frequency;
+ uint32_t gtsc_khz; /* kHz */
+ uint32_t pad0;
struct pl_time pl_time;
struct hvm_io_handler io_handler;
spinlock_t pl_time_lock;
};
-#define ticks_per_sec(v) (v->domain->arch.hvm_domain.tsc_frequency)
-
void pt_save_timer(struct vcpu *v);
void pt_restore_timer(struct vcpu *v);
void pt_update_irq(struct vcpu *v);
uint32_t version; /* File format version */
uint64_t changeset; /* Version of Xen that saved this file */
uint32_t cpuid; /* CPUID[0x01][%eax] on the saving machine */
- uint32_t pad0;
+ uint32_t gtsc_khz; /* Guest's TSC frequency in kHz */
};
DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header);